package com.onpositive.dataminer.value.transformers;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import com.onpositive.dataminer.value.audits.WikiLinksRedirectionAudit;
import com.onpositive.dataminer.value.audits.WikiLinksRedirectionAudit.OwnAuditResult;
import com.onpositive.knowledge.model.value.audits.AbstractAuditResult;
import com.onpositive.knowledge.model.value.audits.GeneralAuditResult;
import com.onpositive.knowledge.model.value.audits.WikiLinksDisambiguationAuditResult;
import com.onpositive.knowledge.model.value.audits.WikiLinksStatisticAudit;
import com.onpositive.knowledge.model.values.AuditAssistedTransformer;
import com.onpositive.knowledge.model.values.DescribedValue;
import com.onpositive.knowledge.model.values.IHasAuditResult;
import com.onpositive.knowledge.model.values.ModifyingValueTraverser;
import com.onpositive.semantic.model.api.property.IProperty;
import com.onpositive.units.ParsedIdent;

public class WikiLinksRedirectionTransformer extends AuditAssistedTransformer {

	private static final long serialVersionUID = 7494918316625325494L;

	public final static String COMMENT_ = "Links redirection audit" ;
	
	public static final String ID = "wiki-links-redirection-transformer";
	
	public WikiLinksRedirectionTransformer(IHasAuditResult source) {
		super(source);
	}
	
	@Override
	public DescribedValue[] adjust(Object object, IProperty prop, DescribedValue... original) {

		AbstractAuditResult aResult = this.getAuditResultSource().getAuditResult() ;
	
		WikiLinksRedirectionAudit.OwnAuditResult redirectionResult = null ;
		WikiLinksDisambiguationAuditResult statisticResult = null ;
		
		if( aResult instanceof WikiLinksRedirectionAudit.OwnAuditResult ){
			redirectionResult = (WikiLinksRedirectionAudit.OwnAuditResult) aResult ;
		}		
		else if( aResult instanceof GeneralAuditResult )
		{			
			GeneralAuditResult generalResult = (GeneralAuditResult) aResult ;
			AbstractAuditResult _res = generalResult.getResult( WikiLinksRedirectionAudit.ID ) ;
			if( _res instanceof WikiLinksRedirectionAudit.OwnAuditResult )
				redirectionResult = (WikiLinksRedirectionAudit.OwnAuditResult) _res ;
			
			AbstractAuditResult __res = generalResult.getResult( WikiLinksStatisticAudit.ID ) ;
			if( __res instanceof WikiLinksDisambiguationAuditResult )
				statisticResult = (WikiLinksDisambiguationAuditResult) __res ;
		}
		if( redirectionResult == null )
			return original ;
		
		HashMap<String,Object> meta = new HashMap<String, Object>() ;
		meta.put("redirection-audit-result" , redirectionResult) ;
		
		if(statisticResult !=null){
			meta.put("statistic-audit-result-general" , statisticResult) ;
			WikiLinksDisambiguationAuditResult pRes
				= statisticResult.getPropertyResult( prop.getId() ) ;
			
			meta.put("statistic-audit-result-property" , pRes) ;
		}
		
		
		Object processed = traverser.iterateValues(null, original, false, meta, 0,false);
		if( !(processed instanceof Object[]) )
			return original ;
		
		Object[] arr = (Object[]) processed ;
		ArrayList<DescribedValue> lst = new ArrayList<DescribedValue>() ; 
		for( Object o : arr ){
			if( o instanceof DescribedValue )
				lst.add((DescribedValue) o) ;
			else
				lst.add( null ) ;
		}
		
		return lst.toArray( new DescribedValue[lst.size()] ) ;
	}
	
	

	ModifyingValueTraverser traverser = new ModifyingValueTraverser() {
		
		@Override
		protected Object process(IProperty prop, Object val, Map<String,Object> meta, int index,boolean cameFromCollection)
		{
			if( !(val instanceof ParsedIdent) )
				return null ;
			
			Object resultObject = meta.get("redirection-audit-result");
			if(!(resultObject instanceof WikiLinksRedirectionAudit.OwnAuditResult))
				return null;
			
			WikiLinksRedirectionAudit.OwnAuditResult result = (OwnAuditResult) resultObject ;
			ParsedIdent ident = (ParsedIdent) val ;
			
			String ref = ident.getRef();
			if(ref==null)
				return null;
			
			String redirect = result.getRedirect(ref);
			if(redirect==null)
				return null;
			
			redirect = redirect.replace('_',' ');
					
			resultObject = meta.get("statistic-audit-result-property");
			String newCaption = getBestCaption(resultObject, redirect);
			
			if(newCaption==null){
				resultObject = meta.get("statistic-audit-result-general");
				newCaption = getBestCaption(resultObject, redirect);
			}
			if(newCaption==null)
				newCaption = redirect;//ident.getCaption();
			
			ParsedIdent newIdent = new ParsedIdent(redirect, newCaption, ident.getComment() + "(" + COMMENT_ +")");
			return newIdent ;			
		}


		private String getBestCaption(Object resultObject, String redirect) {
			
			if(!(resultObject instanceof WikiLinksDisambiguationAuditResult))
				return null;
			
			WikiLinksDisambiguationAuditResult res = (WikiLinksDisambiguationAuditResult) resultObject;
			HashMap<String, String> lcMap = res.getLcMap();
			String newCaption = lcMap.get(redirect.toLowerCase());
			if(newCaption==null)
				return null;
			
			HashMap<String, String> captionCaseMap = res.getCaptionCaseMap();
			String captionWithCase = captionCaseMap.get(newCaption);
			if(captionWithCase!=null){
				newCaption = captionWithCase;
			}
			return newCaption;
		}

				
		@Override
		protected Class<?>[] createTargetClasses() {
			return new Class<?>[]{ ParsedIdent.class };
		}
		
		@Override
		protected Class<?>[] createNecessaryClasses() {
			return new Class<?>[]{ ParsedIdent.class };
		}
	};


	@Override
	public String getId() {
		return ID;
	}
	
}
